<template>
  <div ref="container" class="parking-scene">
    <div v-if="loading" class="loading">
      <div class="progress-bar">
        <div class="progress" :style="{ width: `${loadProgress}%` }"></div>
      </div>
      <div class="progress-text">{{ loadProgress }}%</div>
    </div>
    <div v-if="!loading" class="controls">
      <button @click="toggleGrid">网格: {{ showGrid ? 'ON' : 'OFF' }}</button>
      <button @click="addRandomCar">添加随机车辆</button>
      <button @click="removeRandomCar">移除随机车辆</button>
      <div class="stats">
        车位总数: {{ totalSlots }} | 已占用: {{ occupiedSlots }} | 剩余: {{ totalSlots - occupiedSlots }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, computed ,defineAsyncComponent } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'

// 组件引用
const Vehicle = defineAsyncComponent(() => import('./Vehicle.vue'))
const ParkingSlot = defineAsyncComponent(() => import('./PakingSlot.vue'))

// DOM引用和状态
const container = ref(null)
const loading = ref(true)
const loadProgress = ref(0)
const showGrid = ref(true)
const selectedSlot = ref(null)

// 停车场数据
const parkingSlots = ref(Array(20).fill().map((_, i) => ({
  id: i,
  occupied: false,
  vehicle: null,
  position: {
    x: (i % 5) * 4 - 8,
    y: 0,
    z: Math.floor(i / 5) * 7 - 14
  }
})))

// 计算属性
const totalSlots = computed(() => parkingSlots.value.length)
const occupiedSlots = computed(() => parkingSlots.value.filter(s => s.occupied).length)

// Three.js对象
let scene, camera, renderer, controls, gridHelper, raycaster

// 初始化场景
function initScene() {
  // 1. 创建场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x333333)

  // 2. 创建相机
  camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  )
  camera.position.set(20, 25, 20)
  camera.lookAt(0, 0, 0)

  // 3. 创建渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.shadowMap.enabled = true
  renderer.shadowMap.type = THREE.PCFSoftShadowMap
  container.value.appendChild(renderer.domElement)

  // 4. 添加控制器
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.05
  controls.minDistance = 10
  controls.maxDistance = 50

  // 5. 添加光源
  const ambientLight = new THREE.AmbientLight(0x404040, 0.5)
  scene.add(ambientLight)

  const directionalLight = new THREE.DirectionalLight(0xffffff, 1)
  directionalLight.position.set(10, 20, 10)
  directionalLight.castShadow = true
  directionalLight.shadow.mapSize.width = 2048
  directionalLight.shadow.mapSize.height = 2048
  scene.add(directionalLight)

  // 6. 添加地面
  const groundGeometry = new THREE.PlaneGeometry(50, 50)
  const groundMaterial = new THREE.MeshStandardMaterial({
    color: 0x555555,
    roughness: 0.8,
    metalness: 0.2
  })
  const ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  ground.receiveShadow = true
  scene.add(ground)

  // 7. 添加网格辅助
  gridHelper = new THREE.GridHelper(50, 50, 0x888888, 0x444444)
  scene.add(gridHelper)

  // 8. 初始化射线检测
  raycaster = new THREE.Raycaster()

  // 9. 创建停车位
  createParkingSlots()

  // 10. 添加一些初始车辆
  addRandomVehicles(5)

  loading.value = false
}

// 创建停车位
function createParkingSlots() {
  parkingSlots.value.forEach(slot => {
    const slotComponent = {
      position: slot.position,
      occupied: slot.occupied,
      onClick: () => handleSlotClick(slot.id)
    }
    // 在实际项目中，这里会渲染ParkingSlot组件
    // 本例简化直接创建Three.js对象
    const slotGeometry = new THREE.BoxGeometry(3, 0.1, 5)
    const slotMaterial = new THREE.MeshStandardMaterial({
      color: slot.occupied ? 0xff4444 : 0x44ff44,
      transparent: true,
      opacity: 0.8
    })

    const slotMesh = new THREE.Mesh(slotGeometry, slotMaterial)
    slotMesh.position.set(slot.position.x, slot.position.y, slot.position.z)
    slotMesh.userData = { type: 'slot', id: slot.id }
    slotMesh.castShadow = true
    slotMesh.receiveShadow = true
    scene.add(slotMesh)
  })
}

// 添加随机车辆
function addRandomVehicles(count) {
  const availableSlots = parkingSlots.value.filter(s => !s.occupied)
  const slotsToFill = Math.min(count, availableSlots.length)

  for (let i = 0; i < slotsToFill; i++) {
    const randomIndex = Math.floor(Math.random() * availableSlots.length)
    const slot = availableSlots[randomIndex]
    addVehicleToSlot(slot.id)
    availableSlots.splice(randomIndex, 1)
  }
}

// 添加车辆到指定车位
function addVehicleToSlot(slotId) {
  const slotIndex = parkingSlots.value.findIndex(s => s.id === slotId)
  if (slotIndex === -1 || parkingSlots.value[slotIndex].occupied) return

  // 在实际项目中，这里会渲染Vehicle组件
  // 本例简化直接创建Three.js对象
  const colors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff]
  const color = colors[Math.floor(Math.random() * colors.length)]

  const carGeometry = new THREE.BoxGeometry(2.5, 1.2, 4)
  const carMaterial = new THREE.MeshStandardMaterial({
    color,
    metalness: 0.7,
    roughness: 0.3
  })

  const car = new THREE.Mesh(carGeometry, carMaterial)
  car.position.set(
    parkingSlots.value[slotIndex].position.x,
    0.7,
    parkingSlots.value[slotIndex].position.z
  )
  car.rotation.y = Math.random() * Math.PI * 2
  car.castShadow = true
  car.userData = { type: 'vehicle', slotId }
  scene.add(car)

  // 更新车位状态
  parkingSlots.value[slotIndex].occupied = true
  parkingSlots.value[slotIndex].vehicle = car

  // 更新车位颜色
  updateSlotColor(slotId, true)
}

// 移除随机车辆
function removeRandomCar() {
  const occupiedSlots = parkingSlots.value.filter(s => s.occupied)
  if (occupiedSlots.length === 0) return

  const randomIndex = Math.floor(Math.random() * occupiedSlots.length)
  removeVehicleFromSlot(occupiedSlots[randomIndex].id)
}

// 从车位移除车辆
function removeVehicleFromSlot(slotId) {
  const slotIndex = parkingSlots.value.findIndex(s => s.id === slotId)
  if (slotIndex === -1 || !parkingSlots.value[slotIndex].occupied) return

  // 查找并移除车辆
  const vehicle = parkingSlots.value[slotIndex].vehicle
  scene.remove(vehicle)

  // 更新车位状态
  parkingSlots.value[slotIndex].occupied = false
  parkingSlots.value[slotIndex].vehicle = null

  // 更新车位颜色
  updateSlotColor(slotId, false)
}

// 更新车位颜色
function updateSlotColor(slotId, occupied) {
  const slotMesh = scene.children.find(
    obj => obj.userData?.type === 'slot' && obj.userData.id === slotId
  )
  if (slotMesh) {
    slotMesh.material.color.setHex(occupied ? 0xff4444 : 0x44ff44)
  }
}

// 处理车位点击
function handleSlotClick(slotId) {
  const slot = parkingSlots.value.find(s => s.id === slotId)
  if (!slot) return

  // 取消之前选中的车位
  if (selectedSlot.value !== null) {
    const prevSlotMesh = scene.children.find(
      obj => obj.userData?.type === 'slot' && obj.userData.id === selectedSlot.value
    )
    if (prevSlotMesh) {
      prevSlotMesh.material.emissive.setHex(0x000000)
    }
  }

  // 高亮当前选中的车位
  const slotMesh = scene.children.find(
    obj => obj.userData?.type === 'slot' && obj.userData.id === slotId
  )
  if (slotMesh) {
    slotMesh.material.emissive.setHex(0xffff00)
    selectedSlot.value = slotId
  }

  console.log(`选中车位: ${slotId}`, slot.occupied ? '已占用' : '空闲')
}

// 切换网格显示
function toggleGrid() {
  showGrid.value = !showGrid.value
  gridHelper.visible = showGrid.value
}

// 添加随机车辆按钮
function addRandomCar() {
  addRandomVehicles(1)
}

// 处理场景点击
function onPointerClick(event) {
  // 计算鼠标位置归一化坐标
  const mouse = new THREE.Vector2()
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1

  // 设置射线
  raycaster.setFromCamera(mouse, camera)

  // 计算相交对象
  const intersects = raycaster.intersectObjects(scene.children)

  if (intersects.length > 0) {
    const clickedObject = intersects[0].object
    if (clickedObject.userData?.type === 'slot') {
      handleSlotClick(clickedObject.userData.id)
    }
  }
}

// 动画循环
function animate() {
  requestAnimationFrame(animate)
  controls.update()
  renderer.render(scene, camera)
}

// 窗口大小调整
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
}

onMounted(() => {
  initScene()
  animate()
  window.addEventListener('resize', onWindowResize)
  renderer.domElement.addEventListener('click', onPointerClick)

  // 模拟加载进度
  const interval = setInterval(() => {
    loadProgress.value += 5
    if (loadProgress.value >= 100) {
      clearInterval(interval)
    }
  }, 100)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', onWindowResize)
  renderer.domElement.removeEventListener('click', onPointerClick)
  container.value?.removeChild(renderer.domElement)
})
</script>

<style scoped>
.parking-scene {
  width: 100%;
  height: 100vh;
  position: relative;
}

.loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: white;
}

.progress-bar {
  width: 200px;
  height: 20px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 10px;
}

.progress {
  height: 100%;
  background: linear-gradient(90deg, #4CAF50, #8BC34A);
  transition: width 0.3s;
}

.progress-text {
  font-size: 18px;
}

.controls {
  position: absolute;
  bottom: 20px;
  left: 20px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

button {
  padding: 8px 16px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border: 1px solid #4CAF50;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
}

button:hover {
  background: rgba(76, 175, 80, 0.7);
}

.stats {
  padding: 8px 16px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border-radius: 4px;
}
</style>
